<?php

/***  DOCUMENTATION LAYER

Bafflegate Function Library

Last Update: Aug 2007
Author: Tom at klenwell@gmail.com

FUNCTIONS
  get_client_ip()
  get_client_ip_simple()
  get_client_ip_pphlogger()
  get_proxy()
  extract_first_ip($string)
  is_valid_ip($ip)


NOTES
  some common function used in bafflegate project -- most of these will
  eventually be incorporated into a class
  
  on issue of getting the *real* visitor ip, this is as definitive a discussion
  as I could find: http://php.net/manual/en/function.getenv.php

______________________________________________________________________________*/


// get ip
// source: http://groups.google.com/group/comp.lang.php/msg/02153fb3ddb8a0eb
// see also pphlogger functions.lib.php: get_real_IP()
/*____________________________________________________________________________*/
function get_client_ip() 
{
  $ip = '';
  
  // first we try HTTP_CLIENT_IP
  if ( !empty($_SERVER['HTTP_CLIENT_IP']) )
  {
    $ip = extract_first_ip($_SERVER['HTTP_CLIENT_IP']);
  }
  
  // then HTTP_X_FORWARDED
  elseif ( !empty($_SERVER['HTTP_X_FORWARDED']) )
  {
    $ip = extract_first_ip($_SERVER['HTTP_X_FORWARDED']);
  }
  
  // then HTTP_X_FORWARDED_FOR
  elseif ( !empty($_SERVER['HTTP_X_FORWARDED_FOR']) )
  {
    $ip = extract_first_ip($_SERVER['HTTP_X_FORWARDED_FOR']);
  }
  
  // default: REMOTE_ADDR
  if ( !is_valid_ip($ip) )
  {
    $ip = get_client_ip_simple();
  }

  return $ip;
} 
/*____________________________________________________________________________*/


// get ip address (the simple way)
/*____________________________________________________________________________*/
function get_client_ip_simple() 
{
  $ip = '';
  if ( !empty($_SERVER['REMOTE_ADDR']) ) $ip = $_SERVER['REMOTE_ADDR'];
  return $ip;
} 
/*____________________________________________________________________________*/


// get ip (old pphlogger method)
// source: pphlogger functions.lib.php
/*____________________________________________________________________________*/
function get_client_ip_pphlogger() 
{
  $ip = '';
  
  // Apache must be set up to do hostname lookups
  // why is this any better?
  if ( !empty($_SERVER['REMOTE_HOST']) ) 
  {
    $ip = extract_first_ip($_SERVER['REMOTE_HOST']);
  }
  
  if ( empty($ip) )
  {
    $ip = $_SERVER['REMOTE_ADDR'];
  }
	
	return $ip;
} 
/*____________________________________________________________________________*/


// get proxy (the simple way)
// see pphlogger.php
/*____________________________________________________________________________*/
function get_proxy() 
{
  $proxy = '';
  
  if ( empty($_SERVER['HTTP_VIA']) ) return false;
  
  $proxy = trim(addslashes(urldecode(strstr($_SERVER['HTTP_VIA'],' '))));
  return $proxy;
} 
/*____________________________________________________________________________*/


// extract ip from remote host
// source: pphlogger functions.lib.php
/*____________________________________________________________________________*/
function extract_first_ip($string) 
{
  $ip = '';
  $MATCH = array();
  $regex = '^([0-9]{1,3}\.){3,3}[0-9]{1,3}';
  
  if ( ereg($regex, $string, $_MATCH) )
  {
    $ip = $_MATCH[0];
  }
  
  return $ip;
} 
/*____________________________________________________________________________*/


// is the ip valid?
// source: http://www.teratechnologies.net/stevekamerman/index.php?entry=entry060606-220921
/*____________________________________________________________________________*/
function is_valid_ip($ip) 
{
// *** DATA
  
  // return
  $is_valid = 0;
  
  // reserved IPs
  $_RESERVED_IP = array
  (
    array('0.0.0.0','2.255.255.255'),
    array('10.0.0.0','10.255.255.255'),
    array('127.0.0.0','127.255.255.255'),
    array('169.254.0.0','169.254.255.255'),
    array('172.16.0.0','172.31.255.255'),
    array('192.0.2.0','192.0.2.255'),
    array('192.168.0.0','192.168.255.255'),
    array('255.255.255.0','255.255.255.255')
  );

  
// *** MANIPULATE

  // sanity check
  if ( empty($ip) || ip2long($ip) == -1 ) return 0;

  // check for reserved IP
  foreach ( $_RESERVED_IP as $_LIMIT )
  {
    $_min = ip2long($_LIMIT[0]);
    $_max = ip2long($_LIMIT[1]);
  
    // check range
    if ( (ip2long($ip) >= $_min) && (ip2long($ip) <= $_max) ) return 0;
  }
  
  // still here?  must be valid
  $is_valid = 1;


// *** RETURN

  return $is_valid;
}
/*____________________________________________________________________________*/



// Testbed
/*____________________________________________________________________________*/

if ( 0 )
{
	// test code here
}

/*____________________________________________________________________________*/

?>
